package com.example.websocket.util;

import com.example.websocket.dto.WSMultipleSessionDataDTO;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

public class WSSessionUtil {
    protected static Set<WSMultipleSessionDataDTO> SESSION_DATAS = ConcurrentHashMap.newKeySet();


    public static WSMultipleSessionDataDTO findByUniqueCode(String uniqueCode) {
        for (WSMultipleSessionDataDTO proxyData : SESSION_DATAS) {
            // 如果存在该链接
            if (proxyData.equalsUniqueCode(uniqueCode)) {
                return proxyData;
            }
        }
        return null;
    }


    public static void addSession(WebSocketSession session,String uniqueCode) {
        synchronizedOperate(SESSION_DATAS,datas->{
            WSMultipleSessionDataDTO data = findByUniqueCode(uniqueCode);
            if (Objects.isNull(data)) {
                data = new WSMultipleSessionDataDTO(session, uniqueCode);
                datas.add(data);
            }
            data.addSession(session);
        });
    }

    public static void remove(WebSocketSession session,String uniqueCode) {
        synchronizedOperate(SESSION_DATAS,datas->{
            // token
            WSMultipleSessionDataDTO data = findByUniqueCode(uniqueCode);
            if (Objects.isNull(data)) {
                return;
            }
            data.removeSession(session);
            // 如果session 一出完了关闭客户窜
            if (data.getSessions().isEmpty()) {
                datas.remove(data);
            }
        });
    }
    public static Set<String> uniqueCodes() {
        return SESSION_DATAS.stream().map(WSMultipleSessionDataDTO::getUniqueCode).collect(Collectors.toSet());
    }

    public static boolean isEmpty() {
        return SESSION_DATAS.isEmpty();
    }
    public static void sendTextMessage(String uniqueCode,String message) {
        WSMultipleSessionDataDTO data = findByUniqueCode(uniqueCode);
        if (Objects.isNull(data)) {
            return;
        }
        data.sendMessage(new TextMessage(message));
    }
    public static void sendTextMessageCondition(Function<WSMultipleSessionDataDTO,TextMessage> condition) {
        SESSION_DATAS.forEach(ele->{
            TextMessage apply = condition.apply(ele);
            if (apply!=null) {
                ele.sendMessage(apply);
            }
        });
    }

    /**
     * 使用到 PROXY_DATAS 的时候同步操作
     * */
    protected static<T> void synchronizedOperate(T syncData, Consumer<T> query) {
        synchronized (syncData) {
            query.accept(syncData);
        }
    }
}
